﻿#include "StrategyManager.h"
#include "json/json.h"
#include "JsonTools.h"
#include "OptionManager.h"
#include <QLibrary>
#include <QDir>

#define DefaultStrategy "DefaultStrategy"
StrategyManager::StrategyManager()
{
	readStrategyFile();
}

StrategyManager::~StrategyManager()
{
}

void StrategyManager::InitStrategy()
{
	readStrategyFile();
}

void StrategyManager::SaveStrategy()
{
	saveStrategyFile();
}

StrategyBase * StrategyManager::GetStrategy(const std::string &pSymbol, UsrTradeInterface *tradeHandler)
{
	std::map<std::string, std::string>::iterator itStrategyInfo = m_strategyMap.find(pSymbol);
	std::string strategyName = m_defaultStrategy;
	if (itStrategyInfo != m_strategyMap.end())
	{
		strategyName = itStrategyInfo->second;
	}
	StrategyBase *pStrategy = nullptr;
	std::map<std::string, StrategyBase *>::iterator itStrategy = m_strategyHandle.find(strategyName);
	if (itStrategy != m_strategyHandle.end())
	{
		pStrategy = itStrategy->second;
	}
	if (pStrategy == nullptr)
	{
		QString absStrategyPath = getLibPath(strategyName);
		QLibrary lib(absStrategyPath);
		if (lib.load())
		{
			typedef StrategyBase *(*CreateStrategy)(UsrTradeInterface *tradeHandler);
			CreateStrategy strategyCreator = (CreateStrategy)lib.resolve("CreateStrategy");
			if (strategyCreator)
			{
				pStrategy = strategyCreator(tradeHandler);
				m_strategyHandle[strategyName] = pStrategy;
			}
		}
	}
	return pStrategy;
}

std::string StrategyManager::GetStrategyName(const std::string &pSymbol)
{
	std::map<std::string, std::string>::iterator itStrategyInfo = m_strategyMap.find(pSymbol);
	std::string strategyName;
	if (itStrategyInfo != m_strategyMap.end())
	{
		strategyName = itStrategyInfo->second;
	}
	return strategyName;
}

void StrategyManager::SetDefaultStrategy(const std::string &pDefaultStrategy)
{
	m_strategyMap[DefaultStrategy] = pDefaultStrategy;
}

void StrategyManager::SetStrategy(const std::string &pSymbol, const std::string &pStrategyName)
{
	m_defaultStrategy = pStrategyName;
}

std::string StrategyManager::GetDefaultStrategy()
{
	return m_defaultStrategy;
}

void StrategyManager::saveStrategyFile()
{
	Json::Value strategyRoot;
	strategyRoot[DefaultStrategy] = m_defaultStrategy;
	// 数据准备策略
	for (std::map<std::string, std::string>::iterator it = m_strategyMap.begin(); it != m_strategyMap.end(); ++it)
	{
		strategyRoot[it->first] = it->second;
	}
	JsonTool::JsonToFile(strategyRoot, OptionManager::Instance().GetStrategySettingFile());
}

void StrategyManager::readStrategyFile()
{
	Json::Value strategyRoot;
	JsonTool::FileToJson(OptionManager::Instance().GetStrategySettingFile(), strategyRoot);
	for (Json::Value::iterator it = strategyRoot.begin(); it != strategyRoot.end(); ++it)
	{
		const char *pname = it.name().c_str();
		m_strategyMap[pname] = it->asString();
	}
	if (m_strategyMap.empty())
	{
		return;
	}
	// 查看默认策略
	std::map<std::string, std::string>::iterator itDefStrategy = m_strategyMap.find(DefaultStrategy);
	if (itDefStrategy == m_strategyMap.end())
	{
		// 没有设置默认策略，那么要定义一个默认策略
		std::map<std::string, std::string>::iterator sBeginIt = m_strategyMap.begin();
		m_defaultStrategy = sBeginIt->second;
	}
	else
	{
		m_defaultStrategy = itDefStrategy->second;
	}
}

QString StrategyManager::getLibPath(const std::string pStrategyName)
{
	std::string strategyDir = OptionManager::Instance().GetStrategyDir();
	OptionManager::Instance().MakeSureDir(strategyDir);
	QString qstrategyDir = QString::fromLocal8Bit(strategyDir.c_str());
	//判断路径是否存在
	QDir dir(qstrategyDir);
	if (!dir.exists())
	{
		return "";
	}
	dir.setFilter(QDir::Files | QDir::NoSymLinks);
	QFileInfoList fileList = dir.entryInfoList();
	int file_count = fileList.count();
	if (file_count <= 0)
	{
		return "";
	}
	QString qstrategyName = QString::fromLocal8Bit(pStrategyName.c_str());
	QString strategyFileName;
	for (int i = 0; i < file_count; i++)
	{
		const QFileInfo &file_info = fileList.at(i);
		QString pFileName = file_info.fileName();
		if (pFileName.startsWith(qstrategyName))
		{
			strategyFileName = pFileName;
			break;
		}
	}
	QString absStrategyPath = qstrategyDir + '/' + strategyFileName;
	return absStrategyPath;
}
